package com.zidongxiangxi.rabbit.producer.support;

import com.zidongxiangxi.rabbit.producer.interceptor.RabbitTemplateMethodInterceptor;
import com.zidongxiangxi.rabbit.producer.manager.ProducerManager;
import com.zidongxiangxi.rabbit.producer.manager.RabbitTemplateManager;
import com.zidongxiangxi.rabbit.producer.transaction.listener.TransactionListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

import java.util.List;
import java.util.Objects;

/**
 * rabbit相关bean的后置加工
 *
 * @author chenxudong
 * @date 2020/11/07
 */
public class RabbitTemplateBeanPostProcessor implements BeanPostProcessor, Ordered {
	private final ProducerManager producerManager;
	private final RabbitTemplateManager rabbitTemplateManager;
	private final RabbitConfirmCallback rabbitConfirmCallback;
	private final RabbitTemplateMethodInterceptor rabbitTemplateMethodInterceptor;

	public RabbitTemplateBeanPostProcessor(
			String application,
			ProducerManager producerManager,
			RabbitTemplateManager rabbitTemplateManager,
			List<TransactionListener> transactionListeners
	) {
		this.producerManager = producerManager;
		this.rabbitTemplateManager = rabbitTemplateManager;
		this.rabbitConfirmCallback = new RabbitConfirmCallback(producerManager);
		this.rabbitTemplateMethodInterceptor = new RabbitTemplateMethodInterceptor(application, producerManager, transactionListeners);
	}

	@Override
	public int getOrder() {
		return LOWEST_PRECEDENCE;
	}

	@Override
	public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
		if (Objects.isNull(producerManager) || !(bean instanceof RabbitTemplate)) {
			return bean;
		}
		RabbitTemplate rabbitTemplate = (RabbitTemplate) bean;
		rabbitTemplate.setMandatory(true);
		rabbitTemplate.setConfirmCallback(rabbitConfirmCallback);
		// 将被代理的RabbitTemplate对象存起来
		rabbitTemplateManager.putRabbitTemplate(rabbitTemplate);

		// 产生代理的RabbitTemplate对象
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTarget(rabbitTemplate);
		proxyFactory.addAdvice(rabbitTemplateMethodInterceptor);
		RabbitTemplate rabbitTemplateProxy = (RabbitTemplate)proxyFactory.getProxy();
		rabbitTemplateProxy.getMessageConverter();
		return rabbitTemplateProxy;
	}
}
